package com.producer.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;

/**
 * HttpClient
 * @author Guo Kaixuan
 */
@SuppressWarnings("deprecation")
public class HttpClient {

	private static PoolingHttpClientConnectionManager client;
	private static String EMPTY_STR = "";  
    private static String UTF_8 = "UTF-8";  
    
    private static PoolingHttpClientConnectionManager getManager(){
        if(null == client){
        	synchronized (HttpClient.class) {
				if(null == client) {
					client = new PoolingHttpClientConnectionManager();  
					client.setMaxTotal(50);
					client.setDefaultMaxPerRoute(5);
				}
			}
        }
		return client;  
    }  
    
    /*
     * 创建http连接
     */
    private static CloseableHttpClient getHttpClient(){
   		return HttpClients.custom().setConnectionManager(getManager()).build(); 
    }



	public static Object send(String url, Map<String, String> params) {
		RestTemplate client = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
//        HttpMethod method = HttpMethod.POST;
		headers.add("zrt", "1dcypsz1/2jss1/2j#f00");
		headers.add("Content-Type", "application/json");
		if (url.contains("ucenter")) {
			headers.add("X-SPDT-SERVICE-KUAIBAO","2018-04-03-spdt-service-kuaibao");
		}
		//将请求头部和参数合成一个请求
		org.springframework.http.HttpEntity<Map<String, String>> requestEntity = new org.springframework.http.HttpEntity<>(params, headers);
		//执行HTTP请求，将返回的结构使用 类格式化
		ResponseEntity<Object> response = client.postForEntity(url, requestEntity, Object.class);
		return response.getBody();


	}
    
    /**
     * <P>发送post请求</P>
     * <P>content-type:application/json</P>
     * @param url
     * @param json
     * @return
     * @throws UnsupportedEncodingException
     */
	public static String postJson(String url, String json) {
		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeader("Content-type", "application/json; charset=utf-8");
		httpPost.setHeader("avgx", "csbt34.ydhl12s");
		httpPost.setHeader("zrt", "1dcypsz1/2jss1/2j#f00");
		httpPost.setEntity(new StringEntity(json, UTF_8));
		httpPost.setConfig(RequestConfig.custom().setConnectTimeout(8*1000).setSocketTimeout(16 * 1000).build());
		return getResponse(httpPost);
	}

	public static String postJson(String url, String json, Header... headers) {
		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeaders(headers);
		httpPost.setEntity(new StringEntity(json, UTF_8));
		httpPost.setConfig(RequestConfig.custom().setConnectTimeout(8*1000).setSocketTimeout(16 * 1000).build());
		return getResponse(httpPost);
	}

	/**
	 * 发送Raw格式 post 请求
	 *
	 * @param url     地址
	 * @param headers header
	 * @param rawStr  数据内容
	 * @return
	 */
	public static String postRaw(String url, Map<String, Object> headers, String rawStr) {
		return postRaw(url, headers, rawStr, 8*1000, 16 * 1000);
	}

	public static String postRaw(String url, Map<String, Object> headers, String rawStr, int connectTimeout, int socketTimeout) {
		HttpPost httpPost = new HttpPost(url);
		for (Entry<String, Object> header : headers.entrySet()) {
			httpPost.addHeader(header.getKey(), header.getValue().toString());
		}
		httpPost.setEntity(new StringEntity(rawStr, UTF_8));
		httpPost.setConfig(RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build());
		return getResponse(httpPost);
	}


	/**
	 * 发送表单形式post请求
	 * @param url
	 * @param headers
	 * @param params
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String postParams(String url, Map<String, Object> headers, Map<String, String> params) throws UnsupportedEncodingException {
		HttpPost httpPost = new HttpPost(url);
		for (Entry<String, Object> param : headers.entrySet()) {
			httpPost.addHeader(param.getKey(), param.getValue().toString());
		}
		ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
		httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8));
		httpPost.setConfig(RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(60 * 1000).build());
		return getResponse(httpPost);
	}
	
	/**
	 * 发送表单形式get请求
	 * @param url
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String get(String url) throws UnsupportedEncodingException {
		HttpGet httpPost = new HttpGet(url);
		httpPost.setConfig(RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(5 * 1000).build());
		return getResponse(httpPost);
	}

	/*
	 * 组装数据
	 */
	private static ArrayList<NameValuePair> covertParams2NVPS(Map<String, String> params) {
		ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
		for (Entry<String, String> param : params.entrySet()) {
			pairs.add(new BasicNameValuePair(param.getKey(), param.getValue()));
		}
		return pairs;
	}

	/*
	 * 获得http请求结果
	 */
	private static String getResponse(HttpRequestBase request) {
		CloseableHttpResponse response = null;
		try {
			response = getHttpClient().execute(request);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				String result = EntityUtils.toString(entity, UTF_8);
				return result;
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(response);
			request.releaseConnection();
		}
		return EMPTY_STR;
	}
	
	/*https*/
	private static SSLConnectionSocketFactory createSSLConnSocketFactory() {  
        SSLConnectionSocketFactory sslsf = null;  
        try {  
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {  
  
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
                    return true;  
                }  
            }).build();  
            sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {  
  
                @Override  
                public boolean verify(String arg0, SSLSession arg1) {  
                    return true;  
                }  
  
                @Override  
                public void verify(String host, SSLSocket ssl) throws IOException {  
                }  
  
                @Override  
                public void verify(String host, X509Certificate cert) throws SSLException {  
                }  
  
                @Override  
                public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {  
                }  
            });  
        } catch (GeneralSecurityException e) {  
            e.printStackTrace();  
        }  
        return sslsf;  
    }

	/**
	 * 通过RestTemplate发送post请求
	 * @param url 请求地址
	 * @param params 请求参数
	 * @return 返回json字符串的结果集
	 */
	public static String executePost(String url, Map<String, Object> params) {
		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());
		String jsonString = JSONObject.toJSONString(params);
		org.springframework.http.HttpEntity<String> requestEntity = new org.springframework.http.HttpEntity<String>(jsonString, headers);
		ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
		return responseEntity.getBody();
	}
}
